package com.matuw.androidx.fragment;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.ContextWrapper;

import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;


import com.matuw.android.QinSdk;
import com.matuw.android.log.QLogger;

import java.lang.reflect.Field;

/**
 * @author Shihwan
 * @date 2023/10/11
 */
public class DialogFragmentUtils {

    public static boolean show(FragmentActivity activity, DialogFragment dialog) {
        return show(activity, dialog, dialog.getClass().getName());
    }

    public static boolean show(FragmentActivity activity, DialogFragment dialog, String tag) {
        return isAvailable(activity) && show(activity.getSupportFragmentManager(), dialog, tag);
    }

    public static boolean show(Fragment fragment, DialogFragment dialog) {
        return show(fragment, dialog, dialog.getClass().getName());
    }

    public static boolean show(Fragment fragment, DialogFragment dialog, String tag) {
        if (fragment == null || fragment.isDetached()) {
            return false;
        }
        return show(fragment.getChildFragmentManager(), dialog, tag);
    }

    public static boolean show(FragmentManager manager, DialogFragment dialog, String tag) {
        boolean valid = manager != null && dialog != null;
        if (valid) {
            safeShowDialog(manager, dialog, tag);
        }

        return valid;
    }

    public static void dismiss(DialogFragment dialog) {
        if (dialog != null && dialog.isAdded()) {
            dialog.dismissAllowingStateLoss();
        }
    }

    public static void dismiss(Dialog dialog) {
        if (dialog != null && dialog.isShowing()) {
            Activity activity = findActivity(dialog.getContext());
            if (activity == null) {
                // 可能是使用 Application context 弹出的
                try {
                    dialog.dismiss();
                } catch (Exception e) {
                    if (QinSdk.isLoggable()) QLogger.e("dismiss:" + dialog, e);
                }
            } else if (!activity.isFinishing() && !activity.isDestroyed()) {
                dialog.dismiss();
            }
        }
    }

    private static void safeShowDialog(FragmentManager manager, DialogFragment dialog, String tag) {
        try {
            dismissByTag(manager, tag);

            Class<?> clazz = DialogFragment.class;

            Field dismissed = clazz.getDeclaredField("mDismissed");
            dismissed.setAccessible(true);
            dismissed.set(dialog, false);

            Field shownByMe = clazz.getDeclaredField("mShownByMe");
            shownByMe.setAccessible(true);
            shownByMe.set(dialog, false);

        } catch (Exception e) {
            if (QinSdk.isLoggable()) QLogger.e("show:" + dialog, e);
            // dialog.show(manager, tag);
        }

        manager.beginTransaction()
                .add(dialog, tag)
                .commitAllowingStateLoss();

    }

    public static void dismissByTag(FragmentManager manager, String tag) {
        Fragment fragment = manager.findFragmentByTag(tag);
        if (fragment instanceof DialogFragment) {
            dismiss((DialogFragment) fragment);
        }
    }

    static Activity findActivity(Context context) {
        if (context instanceof Activity) return (Activity) context;
        if (context instanceof ContextWrapper) {
            return findActivity(((ContextWrapper) context).getBaseContext());
        }
        return null;
    }

    static boolean isAvailable(Activity activity) {
        return !(activity == null || activity.isFinishing() || activity.isDestroyed());
    }
}
